package logger

import (
	"context"
	"fmt"
	"time"

	"go.uber.org/zap"
	"gorm.io/gorm/logger"
)

// GormLogger 自定义GORM日志器
type GormLogger struct {
	logger        *Logger
	LogLevel      logger.LogLevel
	SlowThreshold time.Duration
}

// NewGormLogger 创建GORM日志器
func NewGormLogger(log *Logger, level logger.LogLevel, slowThreshold time.Duration) *GormLogger {
	return &GormLogger{
		logger:        log,
		LogLevel:      level,
		SlowThreshold: slowThreshold,
	}
}

// LogMode 设置日志级别
func (l *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
	return &GormLogger{
		logger:        l.logger,
		LogLevel:      level,
		SlowThreshold: l.SlowThreshold,
	}
}

// Info 实现Info方法
func (l *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= logger.Info {
		l.logger.Info(fmt.Sprintf(msg, data...))
	}
}

// Warn 实现Warn方法
func (l *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= logger.Warn {
		l.logger.Warn(fmt.Sprintf(msg, data...))
	}
}

// Error 实现Error方法
func (l *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= logger.Error {
		l.logger.Error(fmt.Sprintf(msg, data...))
	}
}

// Trace 实现Trace方法
func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
	if l.LogLevel <= logger.Silent {
		return
	}

	elapsed := time.Since(begin)
	sql, rows := fc()

	fields := map[string]interface{}{
		"elapsed": elapsed,
		"rows":    rows,
		"sql":     sql,
	}

	switch {
	case err != nil && l.LogLevel >= logger.Error:
		l.logger.WithFields(fields).Error("gorm trace error", zap.Error(err))
	case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
		l.logger.WithFields(fields).Warn(fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold))
	case l.LogLevel >= logger.Info:
		l.logger.WithFields(fields).Info("gorm trace")
	}
}
